package demo;

import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.general.find.PdfTextFind;
import com.spire.pdf.utilities.PdfTable;
import com.spire.pdf.utilities.PdfTableExtractor;
import demo.bean.KzzJcGg;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;

/**
 * @Classname KzzJcFinal
 * @Version 1.0.0
 * @Date 2022/2/24 16:39
 * @Created by yd
 * 可转债减持 提取 最终版
 */
@Slf4j
public class KzzJcFinal {
    /**
     * 解析PDF
     * 读取PDF为text解析
     *
     * @param pdfPath PDF文件路径
     * @return KzzJcGg
     */
    public static KzzJcGg parsePdf(String pdfPath, KzzJcGg kzzJcgg) {
        PdfDocument pdfDoc = new PdfDocument();
        pdfDoc.loadFromFile(pdfPath);
        getKzzCodeAndName(kzzJcgg, pdfDoc);
        // 不能直接按照文本读取，因为有些文本 持有人 换行，导致读取错误。先按照Table
        boolean isTxt = parsePdfByTable(kzzJcgg, pdfDoc);
        if (isTxt) {
            parsePdfByTxt(kzzJcgg, pdfDoc);
        }
        return kzzJcgg;
    }

    /**
     * 以 TXT解析 持有人减持
     *
     * @param kzzJcgg 公告bean
     * @param pdfDoc  PDF文档
     */
    private static void parsePdfByTxt(KzzJcGg kzzJcgg, PdfDocument pdfDoc) {
        System.out.println(StringUtils.center("按照文本解析持有人", 51, "*"));
        StringBuilder sb = new StringBuilder();
        //遍历PDF页面，获取每个页面的文本并添加到StringBuilder对象
        for (int i = 0; i < pdfDoc.getPages().getCount(); i++) {
            sb.append(pdfDoc.getPages().get(i).extractText(false));
        }
        String[] split = StringUtils.substringAfter(sb.toString(), "持有人").split("\\r?\\n");
        System.out.println(StringUtils.substringAfter(sb.toString(), "持有人"));
        KzzJcGg.KzzJcItem kzzJcItem;
        for (String s : split) {
            //将 “李振国  7,214,630  14.43% 965,000 1.93% 6,249,630 12.50% ”
            // 替换为 "李振国  7214630  14.43 965000 1.93 6249630 12.50 "
            s = StringUtils.replaceEach(s, new String[]{",", "%", ""}, new String[]{"", "", ""}).trim();
            if (s.length() > 20) {
                String[] cyrAndNum = StringUtils.split(s);
                if (cyrAndNum.length >= 6) {
                    //至少包含 持有人名称|持有数量|持有比例|减持数量|减持后数量|减持后占比
                    if (!StringUtils.contains(cyrAndNum[0], "合计")) {
                        if (StringUtils.isNumeric(cyrAndNum[1])) {
                            kzzJcItem = new KzzJcGg.KzzJcItem().setCyr(cyrAndNum[0]).setCySl(cyrAndNum[1]).setCyZb(cyrAndNum[2]).setJcNum(cyrAndNum[3]).setJchSl(cyrAndNum[cyrAndNum.length - 2]).setJchZb(cyrAndNum[cyrAndNum.length - 1]);
                            log.info("parseText 【{}】", kzzJcItem);
                            kzzJcgg.getItemList().add(kzzJcItem);
                        }
                    }
                }
            }
        }
    }

    /**
     * 以 Table形式解析PDF,获取持有人减持
     *
     * @param kzzJcgg 公告bean
     * @param pdfDoc  PDF文档
     */
    private static boolean parsePdfByTable(KzzJcGg kzzJcgg, PdfDocument pdfDoc) {
        boolean isTxt = false;
        PdfTableExtractor extractor = new PdfTableExtractor(pdfDoc);
        StringBuilder builder = new StringBuilder();
        FLAG:
        for (int page = 0; page < pdfDoc.getPages().getCount(); page++) {
            //提取页面中的表格存入PdfTable[]数组
            PdfTable[] tableLists = extractor.extractTable(page);
            if (tableLists != null && tableLists.length > 0) {
                //遍历表格
                for (PdfTable table : tableLists) {
                    int row = table.getRowCount();//获取表格行
                    int column = table.getColumnCount();//获取表格列
                    //第一行是减持 部分不需要
                    for (int i = 0; i < row; i++) {
                        //第0,1,2 最后2列是需要的
                        for (int j = 0; j < column; j++) {
                            //获取表格中的文本内容
                            String text = table.getText(i, j);
                            //将获取的text写入StringBuilder容器
                            String replace = StringUtils.replaceEach(text, new String[]{"\n", ",", "%", " "}, new String[]{"", "", "", ""});
                            System.out.print(replace + "\t");
                            builder.append(replace + "|");
                        }
                        System.out.println();
                        String[] split = builder.deleteCharAt(builder.length() - 1).toString().trim().split("\\|");
                        //第一列是持有人，如果获取到的是 数字，那就是 表格不完整，无法使用这种方式(同时排除合计)
                        if (StringUtils.isNumeric(split[0])) {
                            //以免标题添加入(用隆基测试出来的)
                            kzzJcgg.setItemList(new ArrayList<KzzJcGg.KzzJcItem>());
                            isTxt = true;
                            break FLAG;
                        }

                        //合计也需要
                        String columnFirstStr = split[0].trim();
                        //佳力图 减持公告表格 是 股东名称|https://cdn.jsdelivr.net/gh/qianlicao51/files@main/img/202202241758942.png
                        // 白云电气 表头 是多行的 https://cdn.jsdelivr.net/gh/qianlicao51/files@main/img/202202241815386.png
                        if (!StringUtils.equals("合计", columnFirstStr) && !StringUtils.containsAny(columnFirstStr, "持有人", "股东名称") && StringUtils.isNumeric(split[1])) {
                            KzzJcGg.KzzJcItem kzzJcItem = new KzzJcGg.KzzJcItem().setCyr(split[0]).setCySl(split[1]).setCyZb(split[2]).setJcNum(split[3]).setJchSl(split[split.length - 2]).setJchZb(split[split.length - 1]);
                            System.out.println(kzzJcItem);
                            kzzJcgg.getItemList().add(kzzJcItem);
                        }
                        // builder.append(System.getProperty("line.separator"));
                        builder.setLength(0);
                    }
                }
            }
        }

        return isTxt;
    }

    /**
     * 遍历文档页面|只需要第一页就可以获取名字
     *
     * @param kzzJcgg 公告bean
     * @param pdfDoc  PDF文档
     */
    private static void getKzzCodeAndName(KzzJcGg kzzJcgg, PdfDocument pdfDoc) {
        PdfPageBase pdfPageBase = pdfDoc.getPages().get(0);
        PdfTextFind[] finds = pdfPageBase.findText("代码").getFinds();
        //多次循环只能最后一次，因为|https://cdn.jsdelivr.net/gh/qianlicao51/files@main/img/202202240009380.png
        String kzzCode = "";
        String kzzName = "";
        for (PdfTextFind find : finds) {
            String lineText = find.getLineText();
            lineText = StringUtils.trimToEmpty(lineText);
            //将 " 债券代码：113627          债券简称：太平转债"  更改为 “债券代码|113627          债券简称|太平转债”
            lineText = StringUtils.replaceEach(lineText, new String[]{":", "："}, new String[]{"|", "|"});
            //有些是 “债券代码” ，少部分是 "转债代码"
            if (StringUtils.startsWithAny(lineText, "债券代码", "转债代码")) {
                // 从中提取 可转债代码和名称
                kzzCode = StringUtils.substring(lineText, 5, 11);
                kzzJcgg.setKzzCode(kzzCode);
                kzzName = StringUtils.substringAfter(lineText, "简称|");
                kzzJcgg.setKzzName(kzzName);
            }
        }
        System.out.println("code=" + kzzCode + " name=" + kzzName);
    }
}
